`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: HITSZ
// Engineer: 
// 
// Create Date: 2023/11
// Design Name: 
// Module Name: sampling
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module sampling #
(
    parameter integer LED_WIDTH = 24,
    parameter integer SEG_SEGMENT_WIDTH = 8,
    parameter integer SEG_BIT_WIDTH = 8
) 
(
    input wire clk, 
    input wire rstn,
    input wire [LED_WIDTH - 1:0] led, 
    input wire [SEG_SEGMENT_WIDTH - 1:0] seg_segment,
    input wire [SEG_BIT_WIDTH - 1:0] seg_bit,
    input wire tx_done,
    input wire sample_en,
    
    output reg group_done,
    output reg [7:0] tx_data = 0,
    output reg is_duplicated = 1'b0
    );

    // TURN = ceil(SEG_SEGMENT_WIDTH + SEG_BIT_WIDTH + LED_WIDTH / 8)
    // TURN = sample_data_bytes
    localparam integer TURN =  (SEG_SEGMENT_WIDTH + SEG_BIT_WIDTH + LED_WIDTH) % 8 == 0 ?
                                (SEG_SEGMENT_WIDTH + SEG_BIT_WIDTH + LED_WIDTH) / 8 :
                                (SEG_SEGMENT_WIDTH + SEG_BIT_WIDTH + LED_WIDTH) / 8 + 1;
    //  sampling format 
    //  | segment_select | bit_select | led |
    reg [TURN*8 - 1:0] tmp;
    reg [3:0] no_cnt = 4'd0;
    wire[3:0] cnt = (no_cnt == 0 ) ? TURN - 1 : (no_cnt - 1);
    
    always @(posedge clk or negedge rstn) begin
        if (~rstn) begin
            no_cnt <= 4'd0;
            is_duplicated <= 1'b0;
            tmp <= 0;
            group_done <= 1'b1;
            tx_data <= 0;
        end
        else if (sample_en) begin
            // a group of data finished
            if ((no_cnt == TURN - 1) && (tx_done)) begin
                no_cnt <= 4'd0;
                // if SEG_SEGMENT_WIDTH + SEG_BIT_WIDTH + LED_WIDTH % 8 != 0
                // high bit will pad 0, tmp = {0, seg_segment, seg_bit, led}
                tmp <= {seg_segment, seg_bit, led};
                group_done <= 1'b1;
                if (tmp == {seg_segment, seg_bit, led}) begin
                    is_duplicated <= 1'b1;
                end
                else begin
                    is_duplicated <= 1'b0;
                end
            end
            else if (tx_done) begin
                no_cnt <= no_cnt + 1'b1;
                group_done <= 1'b0;
            end
            else begin
                no_cnt <= no_cnt;
                group_done <= group_done;
            end

            // tx_data <= tmp[no_cnt * 8 + 7 : no_cnt * 8]
            // no_cnt
            tx_data <= tmp[(TURN-cnt)*8-1 -: 8];

        end
        else begin
            is_duplicated <= is_duplicated;
            tmp <= tmp;
            no_cnt <= 4'd0;
            group_done <= 1'b1;
            tx_data <= 0;
        end
    end

    

endmodule


